#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->graphicsView->setScene(new QGraphicsScene(this));
    ui->graphicsView->setDragMode(QGraphicsView::ScrollHandDrag);
    ui->degraphicsView->setScene(new QGraphicsScene(this));
    ui->degraphicsView->setDragMode(QGraphicsView::ScrollHandDrag);
    bitmap = NULL;
    debitmap = NULL;
    data = NULL;
    process = new compresor;
    QObject::connect(ui->button_open_bitmap, SIGNAL(clicked()), this, SLOT(open_bitmap()));
    QObject::connect(ui->button_compression, SIGNAL(clicked()), this, SLOT(start_compression()));
    QObject::connect(ui->button_decompression, SIGNAL(clicked()), this, SLOT(start_decompression()));
    QObject::connect(this, SIGNAL(opened_bitmap(QImage*)), process, SLOT(new_bitmap(QImage*)));
    QObject::connect(this, SIGNAL(compress(QString)), process, SLOT(compression_run(QString)));
    QObject::connect(this, SIGNAL(decompress(QString)), process, SLOT(decompression_run(QString)));
    QObject::connect(ui->radioButton_size_8, SIGNAL(clicked()), this, SLOT(block_size_change()));
    QObject::connect(ui->radioButton_size_16, SIGNAL(clicked()), this, SLOT(block_size_change()));
    QObject::connect(ui->radioButton_size_32, SIGNAL(clicked()), this, SLOT(block_size_change()));
    QObject::connect(ui->radioButton_size_global, SIGNAL(clicked()), this, SLOT(block_size_change()));
    QObject::connect(ui->radioButton_alcm, SIGNAL(clicked()), this, SLOT(predictors()));
    QObject::connect(ui->radioButton_darc, SIGNAL(clicked()), this, SLOT(predictors()));
    QObject::connect(ui->radioButton_forward2, SIGNAL(clicked()), this, SLOT(predictors()));
    QObject::connect(ui->radioButton_forward3, SIGNAL(clicked()), this, SLOT(predictors()));
    QObject::connect(ui->radioButton_Graham, SIGNAL(clicked()), this, SLOT(predictors()));
    QObject::connect(ui->radioButton_medmap, SIGNAL(clicked()), this, SLOT(predictors()));
    QObject::connect(ui->radioButton_png, SIGNAL(clicked()), this, SLOT(predictors()));
    QObject::connect(this, SIGNAL(predictor_changed(int)), process, SLOT(predictor_change(int)));
    QObject::connect(this, SIGNAL(block_size_changed(int)), process, SLOT(block_size_changed(int)));
    QObject::connect(process, SIGNAL(bitmap_compressed()), this, SLOT(bitmap_compressed()));
    QObject::connect(process, SIGNAL(bitmap_decompressed(QImage*)), this, SLOT(bitmap_decompressed(QImage*)));
    QObject::connect(process, SIGNAL(new_data(short*)), this, SLOT(new_data(short*)));
    QObject::connect(ui->pushButton_statistic, SIGNAL(clicked()), this, SLOT(statistic()));
    process->start();
    time.start();
    //qDebug() << "start";
}

MainWindow::~MainWindow()
{
    delete ui;
    delete bitmap;
    process->terminate();
    if (process->isFinished())
        delete process;
}

void MainWindow::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void MainWindow::open_bitmap()
{
    delete bitmap;
    bitmap = new QImage;
    picture = QFileDialog::getOpenFileName(this, "Otworz plik ...", 0, "Images (*.bmp *.jpg)");
    bitmap->load(picture);
    ui->graphicsView->scene()->clear();
    ui->graphicsView->scene()->addPixmap (QPixmap::fromImage (*bitmap));
    ui->graphicsView->setSceneRect(0, 0, bitmap->width (), bitmap->height ());
    emit opened_bitmap(bitmap);
}

void MainWindow::start_compression()
{
    file = QFileDialog::getSaveFileName(this, "Zapisz plik", 0, "Skompresowany plik (*.kod)");
    if (file != "")
    {
        time.restart();
        emit compress(file);
    }
}

void MainWindow::start_decompression()
{
    defile = QFileDialog::getOpenFileName(this, "Otworz plik", 0, "Skompresowany plik (*.kod)");
    if (defile != "")
    {
        time.restart();
        emit decompress(defile);
    }
}

void MainWindow::block_size_change()
{
    int block_size;
    if (ui->radioButton_size_8->isChecked())
        block_size = 8;
    if (ui->radioButton_size_16->isChecked())
        block_size = 16;
    if (ui->radioButton_size_32->isChecked())
        block_size = 32;
    if (ui->radioButton_size_global->isChecked())
        block_size = 0;
    //qDebug() << "block size main window";
    emit block_size_changed(block_size);
}

void MainWindow::predictors()
{
    int predictor;
    if (ui->radioButton_forward2->isChecked())
    {
        block_size_unlock();
        predictor = 0;
    }
    if (ui->radioButton_forward3->isChecked())
    {
        block_size_unlock();
        predictor = 1;
    }
    if (ui->radioButton_png->isChecked())
    {
        block_size_lock();
        predictor = 2;
    }
    if (ui->radioButton_medmap->isChecked())
    {
        block_size_lock();
        predictor = 3;
    }
    if (ui->radioButton_Graham->isChecked())
    {
        block_size_lock();
        predictor = 4;
    }
    if (ui->radioButton_darc->isChecked())
    {
        block_size_lock();
        predictor = 5;
    }
    if (ui->radioButton_alcm->isChecked())
    {
        block_size_unlock();
        predictor = 6;
    }
    emit predictor_changed(predictor);
}

void MainWindow::block_size_lock()
{
    ui->radioButton_size_8->setDisabled(true);
    ui->radioButton_size_16->setDisabled(true);
    ui->radioButton_size_32->setDisabled(true);
    ui->radioButton_size_global->setDisabled(true);
}

void MainWindow::block_size_unlock()
{
    ui->radioButton_size_8->setDisabled(false);
    ui->radioButton_size_16->setDisabled(false);
    ui->radioButton_size_32->setDisabled(false);
    ui->radioButton_size_global->setDisabled(false);
}

void MainWindow::bitmap_compressed()
{
    compression_time = time.elapsed();
    QMessageBox::information(this,"Kompresja","Kompresja skonczona");
}

void MainWindow::bitmap_decompressed(QImage *image)
{
    decompression_time = time.elapsed();
    delete debitmap;
    debitmap = image;
    ui->degraphicsView->scene()->clear();
    ui->degraphicsView->scene()->addPixmap (QPixmap::fromImage (*debitmap));
    ui->degraphicsView->setSceneRect(0, 0, debitmap->width (), debitmap->height ());
    QMessageBox::information(this,"Kompresja","Dekompresja skonczona");
}

void MainWindow::new_data(short *value)
{
    data = value;
}

void MainWindow::statistic()
{
    if ((picture == "") || (defile == ""))
    {
        QMessageBox::information(this,"Statystyka","Nie zrobione kompresji lub dekompresji, do poprawnego działania wykonaj obie te czynnosci");
    }
    else
    {
        QFile compress_file(defile);
        QFile oryginal_file(picture);
        mean = 0;
        var = 0;
        //compress_file.open(defile);
        //oryginal_file.open(file);
        bitrate = 8.0*compress_file.size()/(bitmap->width()*bitmap->height());
        //qDebug() <<  oryginal_file.size() << compress_file.size();
        float oryginal = oryginal_file.size();
        float compress = compress_file.size();
        CP = (1.0-1.0/((8.0*oryginal)/(8.0*compress)))*100.0;
        for (int i = 0; i < bitmap->width()*bitmap->height()*3; i++)
        {
            mean += data[i];
            //qDebug() << data[i] << mean;
        }
        mean = mean/((bitmap->width()*bitmap->height()*3));
        for (int i = 0; i < bitmap->width()*bitmap->height()*3; i++)
            var += (data[i]-mean)*(data[i]-mean);
        var = var/((bitmap->width()*bitmap->height()*3));
        QString test = QString("Statystyka kompresji i dekompresji \n Czas kompresji: %1ms \n Czas dekompresji: %2ms \n Srednia bitowa: %L3 b/pixel \n Wspolczynnik kompresji: %L4% \n Wartosc srednia bledu predykcji: %L5 \n Wariancja bledu predykcji: %L6").arg(compression_time).arg(decompression_time).arg(bitrate).arg(CP).arg(mean).arg(var);
        QMessageBox::information(this, "Statystyka", test);
    }
}
